
#ifndef CMD_OBJ_H
#define CMD_OBJ_H

#include <stdio.h>
#include <stdint.h>
#include <sys/time.h>
#include <iostream>
#include "intf_auth_info.h"

class CCmdObj 
: public IAuthInfo
{
public:
	static bool isRequest(uint32_t ulCmdId) 
	{ return ((ulCmdId & 0x00001000) == 0x00001000); }

	static bool isStateful(uint32_t ulCmdId) 
	{ return ((ulCmdId & 0x00000FFF) >= 0x00000801); }

	static bool isAuxSvr(uint32_t ulCmdId) 
	{ return ((ulCmdId & 0xFF000000) == 0xFF000000); }

	static uint32_t Cmd2CateId(uint32_t ulCmdId) 
	{ return (ulCmdId & 0xFFFF0000); }

	static uint32_t getCurrentTimestamp()
	{
	    const long BASE_SECONDS = 1160370232;
	    struct timeval m_tvStart;
	    ::gettimeofday(&m_tvStart, NULL);
	    return ((m_tvStart.tv_sec - BASE_SECONDS) * 1000 + m_tvStart.tv_usec / 1000);
	}

public:
	CCmdObj() 
	    : m_pBuf(NULL)
	    , m_nLen(0)
	    , m_pRawBuf(NULL)
	    , m_nRawLen(0)
	    , m_ulCmdId(0)
	    , m_ulUin(0)
	    , m_ulOperatorUin(0)
	    , m_ulOperatorClientIP(0) 
	    , m_wVersion(2)
	    , m_dwPkgTimestamp(0)
	    {}

	uint32_t getPkgOverTime() // ms
	{
	    return (CCmdObj::getCurrentTimestamp() - this->getPkgTimestamp());
	}

	void Reset()
	{
	    m_pBuf = NULL;
	    m_nLen = 0;
	    m_ulCmdId = 0;

	    m_ulOperatorUin = 0;
	    m_ulOperatorClientIP = 0;
	    m_sOperatorKey.resize(0);
	}

	void setBuffer(char* pBuf, uint32_t nLen)
	{
	    m_pBuf = pBuf;
	    m_nLen = nLen;
	}

	void getBuffer(char*& pBuf, uint32_t& nLen)
	{
	    pBuf = m_pBuf;
	    nLen = m_nLen;
	}

	void setRawBuffer(char* pBuf, uint32_t nLen)
	{
	    m_pRawBuf = pBuf;
	    m_nRawLen = nLen;
	}

	void getRawBuffer(char*& pBuf, uint32_t& nLen)
	{
	    pBuf = m_pRawBuf;
	    nLen = m_nRawLen;
	}

	void setAuthInfo(
		uint32_t ulOperatorUin,
		uint32_t ulOperatorClientIP, 
		const std::string& sOperatorKey)
	{
	    m_ulOperatorUin = ulOperatorUin;
	    m_ulOperatorClientIP = ulOperatorClientIP;
	    m_sOperatorKey = sOperatorKey;
	}

	void setUin(uint32_t ulUin) { m_ulUin = ulUin; }
	uint32_t getUin() const { return m_ulUin; }

	const char* getBuffer() const { return m_pBuf; }
	uint32_t getBufferLen() const { return m_nLen; }

	void setCmdId(uint32_t ulCmdId) { m_ulCmdId = ulCmdId; }
	uint32_t getCmdId() const { return m_ulCmdId; }

	bool isValid(uint32_t ulCmdId) const { return (m_ulCmdId == ulCmdId); }
	bool isRequest() const { return ((m_ulCmdId & 0x00001000) == 0x00001000); }
	bool isStateful() const { return ((m_ulCmdId & 0x00000FFF) >= 0x00000801); }
	bool isAuxSvr() const { return ((m_ulCmdId & 0xFF000000) == 0xFF000000); }

	void Dump(std::ostream& os) {};

	void setVersion(uint16_t wVersion) { m_wVersion = wVersion; }
	uint16_t getVersion() const { return m_wVersion; }

	void setPkgTimestamp(uint32_t dwPkgTimestamp) { m_dwPkgTimestamp = dwPkgTimestamp; }
	uint32_t getPkgTimestamp() const { return m_dwPkgTimestamp; }
	
public:
	virtual uint32_t getOperatorUin() const { return m_ulOperatorUin; }
	virtual uint32_t getOperatorClientIP() const { return m_ulOperatorClientIP; }
	virtual const std::string& getOperatorKey() const { return m_sOperatorKey; }

	void setNetioClientIP(uint32_t dwNetioClientIP) { m_dwNetioClientIP = dwNetioClientIP; }
	uint32_t getNetioClientIP() const { return m_dwNetioClientIP; }

	void setSerialNo(uint32_t dwSerialNo) { m_dwSerialNo = dwSerialNo; }
	uint32_t getSerialNo() const { return m_dwSerialNo; }

private:
	char* m_pBuf;
	uint32_t m_nLen;
	char* m_pRawBuf;
	uint32_t m_nRawLen;
	uint32_t m_ulCmdId;

	uint32_t m_ulUin;
	uint32_t m_ulOperatorUin; 
	uint32_t m_ulOperatorClientIP;
	std::string m_sOperatorKey;

	uint16_t m_wVersion;

	uint32_t m_dwPkgTimestamp;
	uint32_t m_dwNetioClientIP;
	uint32_t m_dwSerialNo;
};

#endif /* CMD_OBJ_H */

